<template>
  <!---搜索表单-->
  <div class="search-div">
    <el-form
      label-width="70px"
      size="small"
      :model="searchModel"
      ref="formSearchRef"
    >
      <el-row>
        <el-col :span="12">
          <el-form-item label="关键字" prop="keyword">
            <el-input
              style="width: 100%"
              placeholder="用户名"
              v-model="searchModel.keyword"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="创建时间">
            <el-date-picker
              v-model="timeRange"
              type="daterange"
              range-separator="To"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row style="display: flex">
        <el-button type="primary" size="small" @click="searchBtn">
          搜索
        </el-button>
        <el-button size="small" @click="resetBtn">重置</el-button>
      </el-row>
    </el-form>
  </div>

  <!--添加按钮-->
  <div class="tools-div">
    <el-button type="success" size="small" @click="addBtn">添 加</el-button>
  </div>

  <!---数据表格-->
  <el-table :data="list" style="width: 100%">
    <el-table-column type="index" width="120" label="序号" />
    <el-table-column prop="userName" label="用户名" />
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="phone" label="手机" />
    <el-table-column prop="avatar" label="头像" #default="scope">
      <img :src="scope.row.avatar" width="50" />
    </el-table-column>
    <el-table-column prop="description" label="描述" />
    <el-table-column prop="status" label="状态" #default="scope">
      {{ scope.row.status == 1 ? '正常' : '停用' }}
    </el-table-column>
    <el-table-column prop="createTime" label="创建时间" />
    <el-table-column label="操作" align="center" width="280">
      <template #default="scope">
        <el-button type="primary" size="small" @click="editBtn(scope.row)">
          修改
        </el-button>
        <el-button type="danger" size="small" @click="deleteBtn(scope.row)">
          删除
        </el-button>
        <el-button
          type="warning"
          size="small"
          @click="assignRoleBtn(scope.row)"
        >
          分配角色
        </el-button>
      </template>
    </el-table-column>
  </el-table>
  <!-- 弹框 -->
  <el-dialog v-model="dialogVisible" :title="title" width="40%">
    <el-form
      label-width="120px"
      :model="formModel"
      ref="formRef"
      :rules="rules"
    >
      <el-form-item label="用户名" prop="userName">
        <el-input v-model="formModel.userName" />
      </el-form-item>
      <el-form-item v-if="!formModel.id" label="密码" prop="password">
        <el-input type="password" show-password v-model="formModel.password" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="formModel.status">
          <el-option label="启用" :value="1" />
          <el-option label="禁用" :value="0" />
        </el-select>
      </el-form-item>
      <el-form-item label="姓名" prop="name">
        <el-input v-model="formModel.name" />
      </el-form-item>
      <el-form-item label="手机" prop="phone">
        <el-input v-model="formModel.phone" />
      </el-form-item>
      <el-form-item label="头像" prop="avatar">
        <el-upload
          class="avatar-uploader"
          action="/api/common/uploadFile"
          :headers="headers"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
        >
          <img v-if="formModel.avatar" :src="formModel.avatar" class="avatar" />
          <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
        </el-upload>
      </el-form-item>
      <el-form-item label="描述" prop="description">
        <el-input v-model="formModel.description" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitBtn">提交</el-button>
        <el-button @click="cancelBtn">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
  <!-- 分配角色弹框 -->
  <el-dialog v-model="dialogRoleVisible" title="分配角色" width="40%">
    <el-form label-width="80px">
      <el-form-item label="用户名">
        <el-input disabled :value="formModel.userName"></el-input>
      </el-form-item>
      <el-form-item label="角色列表">
        <el-checkbox-group v-model="userRoleIds">
          <el-checkbox v-for="role in allRoles" :key="role.id" :label="role.id">
            {{ role.roleName }}
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="submitAssignRole">提交</el-button>
        <el-button @click="dialogRoleVisible = false">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
  <el-pagination
    :page-sizes="[10, 20, 50, 100]"
    :page-size="searchModel.pageSize"
    layout="total, sizes, prev, pager, next"
    :total="total"
    @current-change="handleCurrentChange"
    @size-change="handleSizeChange"
  />
</template>

<script setup>
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
import {
  getUserList,
  addUser,
  editUser,
  deleteUser,
  assignRole,
  getRoleIds,
} from '@/api/sysUser.js'
import { getRoleList } from '@/api/sysRole'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useApp } from '@/pinia/modules/app.js'
//请求头信息
const headers = computed(() => {
  return {
    token: useApp().authorization.token,
  }
})
//定义角色查询参数
const queryModel = reactive({
  pageNum: 1,
  pageSize: 1000,
})
//定义弹框
const dialogVisible = ref(false)
const title = ref('') //弹框标题
//定义一个类型判断是否是添加或者编辑操作
const type = ref('0') //默认0添加1编辑
const formRef = ref() //弹框的表单选择器
const formModel = reactive({
  id: '',
  userName: '',
  name: '',
  phone: '',
  password: '',
  description: '',
  avatar: '',
  status: '', //状态
})
// 表格数据模型
const list = ref([
  {
    id: 1,
    userName: 'admin',
    name: 'admin',
    phone: '13121034567',
    status: 1,
    createTime: '2023-05-11',
  },
  {
    id: 2,
    userName: 'admin',
    name: 'admin',
    phone: '13121034567',
    status: 1,
    createTime: '2023-05-11',
  },
])
// 角色列表
const userRoleIds = ref([])
const allRoles = ref([
  { id: 1, roleName: '管理员' },
  { id: 2, roleName: '业务人员' },
  { id: 3, roleName: '商品录入员' },
])
const dialogRoleVisible = ref(false)
//分配角色按钮
const assignRoleBtn = async row => {
  await Object.assign(formModel, row)
  await getRole()
  await getUserRoleIds(row.id)
  dialogRoleVisible.value = true
}
//获取用户绑定的角色id集合
const getUserRoleIds = async id => {
  let res = await getRoleIds(id)
  if (res.code == 200) {
    userRoleIds.value = res.data
  }
}
//提交分配角色申请
const submitAssignRole = async () => {
  let assignRoleDto = {
    userId: formModel.id,
    roleIdList: userRoleIds.value,
  }
  const res = await assignRole(assignRoleDto)
  if (res.code == 200 && res) {
    ElMessage.success(res.message)
    dialogRoleVisible.value = false
    searchBtn()
  } else {
    ElMessage.error(res.message)
  }
}
//查询所有角色
const getRole = async () => {
  const res = await getRoleList(queryModel)
  if (res.code == 200 && res) {
    allRoles.value = res.data.list
  }
}
//定义一个搜索表单对象获取
const formSearchRef = ref()
//查询参数模型
const searchModel = reactive({
  keyword: '',
  pageNum: 1,
  pageSize: 10,
  createTime: '',
  updateTime: '',
})
//表单校验规则
const rules = reactive({
  name: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 2, max: 9, message: '长度在 2到 9 个字符', trigger: 'blur' },
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    {
      pattern: /^1[3-9]\d{9}$/,
    },
  ],
  userName: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' },
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 12, message: '长度在 6 到 12 个字符', trigger: 'blur' },
  ],
  description: [
    { required: true, message: '请输入描述', trigger: 'blur' },
    { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' },
  ],
  avatar: [{ required: false, message: '请上传头像', trigger: 'blur' }],
})
//定义一个时间存储
const timeList = ref([])
// 分页条数据模型
const total = ref(0)
// 使用计算属性处理时间范围
const timeRange = computed({
  get() {
    return timeList.value
  },
  set(value) {
    timeList.value = value || []
    if (value && value.length === 2) {
      searchModel.createTime = value[0]
      searchModel.updateTime = value[1]
    } else {
      searchModel.createTime = ''
      searchModel.updateTime = ''
    }
  },
})

//查询用户列表
const searchBtn = async () => {
  const res = await getUserList(searchModel)
  if (res.code === 200 && res) {
    list.value = res.data.list
    total.value = res.data.total
  } else {
    ElMessage.error(res.message)
  }
}
//添加按钮
const addBtn = () => {
  title.value = '添加用户'
  type.value = '0'
  Object.assign(formModel, {
    id: '',
    userName: '',
    name: '',
    phone: '',
    password: '',
    description: '',
    avatar: '',
    status: '', //状态
  })
  dialogVisible.value = true
}
//修改按钮
const editBtn = row => {
  type.value = '1'
  dialogVisible.value = true
  title.value = '修改用户'
  Object.assign(formModel, row) //赋值
}
//删除按钮
const deleteBtn = row => {
  ElMessageBox.confirm('此操作将永久删除该记录, 是否继续?', 'Warning', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(async () => {
    const res = await deleteUser(row.id)
    if (res.code === 200 && res) {
      ElMessage.success(res.message)
      searchBtn()
    } else {
      ElMessage.error(res.message)
    }
  })
}
//取消按钮
const cancelBtn = () => {
  nextTick(() => {
    formRef.value.resetFields()
  })
  dialogVisible.value = false
}
//表单提交
const submitBtn = async () => {
  // 先进行表单校验
  if (!formRef.value) {
    ElMessage.warning('表单未初始化')
    return
  }

  try {
    const isValid = await formRef.value.validate()
    if (!isValid) {
      ElMessage.warning('请检查表单填写是否正确')
      return
    }
    let res = null
    if (type.value === '0') {
      res = await addUser(formModel)
    } else {
      res = await editUser(formModel)
    }

    if (res.code === 200 && res) {
      ElMessage.success(res.message)
      dialogVisible.value = false
      searchBtn()
    } else {
      ElMessage.error(res.message)
    }
  } catch (error) {
    ElMessage.error('表单校验失败')
  }
}
//成功上传图片后
const handleAvatarSuccess = (res, file) => {
  formModel.avatar = res.data
}
//重置按钮
const resetBtn = () => {
  nextTick(() => {
    formSearchRef.value.resetFields()
  })
  // 通过计算属性重置时间范围
  timeRange.value = []
}
//当前页变化
const handleCurrentChange = pageNum => {
  searchModel.pageNum = pageNum
  searchBtn()
}
//当前页大小变化
const handleSizeChange = pageSize => {
  searchModel.pageSize = pageSize
  searchBtn()
}
onMounted(() => {
  searchBtn()
})
</script>

<style scoped>
.search-div {
  margin-bottom: 10px;
  padding: 10px;
  border: 1px solid #ebeef5;
  border-radius: 3px;
  background-color: #fff;
}
.tools-div {
  margin: 10px 0;
  padding: 10px;
  border: 1px solid #ebeef5;
  border-radius: 3px;
  background-color: #fff;
}
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>